#######这一模块改自别人代码。
#######主要计算了一些时间差之类的特征。
#######主要通过DataFrame数据结构来实现

import os
import re
import sys
from copy import deepcopy

import pandas as pd
def get_root_dir(path):
    path_list=path.split(os.path.sep)
    index=path_list.index("featurelib")
    return os.path.sep.join(path_list[:index+1])

class CallUnBase0V1Module3:

    def __init__(self):
        self._week_dict = {
            "Sunday": 0,
            "Monday": 1,
            "Tuesday": 2,
            "Wednesday": 3,
            "Thursday": 4,
            "Friday": 5,
            "Saturday": 6,
        }
        self.time_win_dict = {
            sys.maxsize: "all",
            360: "m12",
            180: "m6",
            90: "m3",
            30: "m1",
            14: "d14",
            7: "d7",
            3: "d3",
        }
        cur_path = os.path.abspath(".")
        root_path = get_root_dir(cur_path)
        path = os.path.join(
            root_path,
            "feature_conf",
            "call",
            "un",
            "call_un_base0_v1",
            "call_un_base0_v1_module3.featlist",
        )
        self.res_map = {
            k.strip().split("|")[0].strip(): "None"
            for k in open(path, encoding="utf-8")
        }

    def gen_context(self, data=None) -> tuple:
        data["call_list"] = sorted(
            map(self._gen_tag, data["call_list"]),
            key=lambda x: x["calltime"],
            reverse=False,
        )
        # 与上一个通话的gap day
        if len(data["call_list"]) > 0:
            data["call_list"][0]["gap_day"] = None
            for i in range(1, len(data["call_list"])):
                data["call_list"][i]["last_call_time"] = data["call_list"][i - 1][
                    "calltime"
                ]
                data["call_list"][i]["gap_day"] = (
                    data["call_list"][i]["calltime"].date()
                    - data["call_list"][i]["last_call_time"].date()
                ).days
        self.data = deepcopy(data)

    def _gen_tag(self, call_entity: dict) -> dict:
        call_entity["week_day_name"] = call_entity["calltime"].weekday()
        call_entity["week_day_idx"] = (call_entity["week_day_name"] + 1) % 7
        call_entity["week_is_01"] = int(call_entity["week_day_idx"] in [0, 1])
        for k, v in self.time_win_dict.items():
            call_entity[v] = bool(call_entity["diff_days"] <= k)
        return call_entity

    def fun1(self) -> tuple:
        res_map = deepcopy(self.res_map)
        df = pd.DataFrame(self.data["call_list"])
        for time_win, time_win_str in self.time_win_dict.items():
            res_df = (
                df[df.diff_days <= time_win]
                .agg(
                    {
                        "diff_days": ["max", "min"],
                        "gap_day": ["max", "min", "std", "mean"],
                    }
                )
                .rename(
                    index={"mean": "avg"},
                    columns=dict(diff_days="dfday", gap_day="gpday"),
                )
                .fillna(0)
            )
            res_df_week01 = (
                df[(df.diff_days <= time_win) & (df.week_is_01 == 1)]
                .agg(
                    {
                        "diff_days": ["max", "min"],
                        "gap_day": ["max", "min", "std", "mean"],
                    }
                )
                .rename(
                    index={"mean": "avg"},
                    columns=dict(diff_days="dfday", gap_day="gpday"),
                )
                .fillna(0)
            )
            for i in res_df.index:
                for j in res_df.columns:
                    res_map["_".join([j, i, time_win_str])] = res_df.loc[i, j]
                    res_map["_".join(["wk01", j, i, time_win_str])] = res_df_week01.loc[
                        i, j
                    ]
        update_res = {}
        for k, v in res_map.items():
            if "_max_" in k and "dfday" in k:
                update_res[k.replace("_max_", "_gpday_")] = (
                    v - res_map[k.replace("_max_", "_min_")]
                )
                continue
        res_map.update(update_res)
        return res_map

    def main(self, data):
        self.gen_context(data)
        res_map = self.fun1()
        return res_map
